package main

import (
	"fmt"
)

func main() {
	//初始话链表
	list := List{}
	list.Append(2)
	list.Append(3)
	list.Add(4)
	fmt.Println("list length:", list.Length())
	list.ShowList()

}

type Object interface {
}

type Node struct {
	Data Object
	Next *Node
}

type List struct {
	headNode *Node
}

func (l *List) IsEmpty() bool {
	if l.headNode == nil {
		return true
	} else {
		return false
	}

}

//3. 获得列表长度
func (this *List) Length() int {
	//	获取链表的头结点
	cur := this.headNode
	//定义一个计数器，初始值为0
	count := 0
	for cur != nil {
		count++
		//对地址进行逐个移位
		cur = cur.Next

	}

	return count
}

//4. 从链表的头部添加元素
func (this *List) Add(data Object) *Node {
	node := &Node{Data: data}
	node.Next = this.headNode
	this.headNode = node
	return node

}

//5. 从链表尾部添加元素
func (l *List) Append(data Object) {
	node := &Node{Data: data}
	if l.IsEmpty() {
		l.headNode = node
	} else {
		cur := l.headNode
		for cur.Next != nil {
			cur = cur.Next
		}
		cur.Next = node
	}
}

// 6. 在链表指定位置添加元素
func (this *List) Insert(index int, data Object) {
	if index < 0 { //如果index<0,则进行头部插入
		this.Add(data)
	} else if index > this.Length() { //如果index>链表长度，则进行尾部插入
		this.Append(data)
	} else {
		pre := this.headNode
		count := 0
		for count < (index - 1) { //用于控制位移的链表数目
			pre = pre.Next
			count++
		}
		//	当循环退出后，pre指向index-1的位置
		node := &Node{Data: data}
		node.Next = pre.Next
		pre.Next = node
	}

}

//7. 删除链表指定值的元素
func (this *List) Remove(data Object) {
	pre := this.headNode //定义变量pre,存储头结点
	if pre.Data == data {
		this.headNode = pre.Next
	} else { //如果删除的不是头结点
		for pre.Next != nil { //循环遍历到到最后一个节点，如果不是，则进行如下判断
			if pre.Next.Data == data {
				pre.Next = pre.Next.Next
				//如果pre.Next的节点数据等于data,那么删除改节点，pre.Next指向该节点之后的节点地址
			} else {
				pre = pre.Next
			}
		}

	}
}

//8.删除指定位置的元素
func (this *List) RemoveIndex(index int) {
	pre := this.headNode
	if index <= 0 { //如果index为0或者小于0，那么删除头结点
		this.headNode = pre.Next
	} else if index > this.Length() {
		fmt.Println("超出链表的长度")
	} else {
		count := 0 //定义计数器
		for count != (index-1) && pre.Next != nil {
			count++
			pre = pre.Next
		}
		pre.Next = pre.Next.Next
	}
}

//9.查看链表中是否包含某个元素
func (this *List) Contain(data Object) bool {
	cur := this.headNode
	for cur != nil {
		if cur.Data == data {
			return true
		} else {
			cur = cur.Next
		}
	}
	return false
}

//10.遍历所有节点
func (l *List) ShowList() {
	if !l.IsEmpty() {
		cur := l.headNode
		for {
			fmt.Printf("\t%v", cur.Data)
			if cur.Next != nil {
				cur = cur.Next
			} else {
				break
			}

		}
	}

}

//https://studygolang.com/articles/13795
